package com.cardeira.sendsms.client;

import java.util.ArrayList;
import java.util.Date;


import com.cardeira.sendsms.client.data.SmsEntry;
import com.cardeira.sendsms.client.data.SmsState;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Sendsms implements EntryPoint {
	
	/**
	 * Create a remote service proxy to talk to the server-side Greeting service.
	 */
	private final SMSServiceAsync smsService = GWT
			.create(SMSService.class);

	private ArrayList<SmsEntry> entries = new ArrayList<SmsEntry>();
	final Grid grid = new Grid(0,5);
	final TextBox txtPhoneNumber = new TextBox();
	final ListBox cmbHour = new ListBox();
	final ListBox cmbNetCode = new ListBox();
	final ListBox cmbDay = new ListBox();
	final ListBox cmbClinica = new ListBox();

	
	final Timer timer = new Timer(){
	      @Override
	      public void run() {
	        
	    	  refreshData();
	      }

	    };

		private void refreshData() {
			ArrayList<String> al = new ArrayList<String>();
			
			for (int i=0; i<entries.size(); i++)
			{
				if (entries.get(i).getState()!=SmsState.ENTREGUE && entries.get(i).getState()!=SmsState.ERRO && entries.get(i).getId()!=null)
					al.add(entries.get(i).getId());
			}
			
			if (al.size()>0)
			{
				smsService.getStatus((String[])al.toArray( new String[al.size()]), 
					new AsyncCallback<int[]>() {
						public void onFailure(Throwable caught) {
							;
						}

						public void onSuccess(int[] result) {
							updateStatus(result);
						}

					});
			}
			refreshGrid();
		}
		
		final Button sendButton = new Button("Enviar");
		final DialogBox dialogBox = new DialogBox();
		final Label textToServerLabel = new Label();
		final HTML serverResponseLabel = new HTML();
		VerticalPanel dialogVPanel = new VerticalPanel();
		final Button closeButton = new Button("Close");
		

		private void updateStatus(int[] result) {
			int j=0;
			for (int i=0; i<result.length; i++)
			{
				for (; j<entries.size(); j++)
					if (entries.get(j).getState()!= SmsState.ENTREGUE && entries.get(j).getState()!= SmsState.ERRO && entries.get(j).getId()!=null)
					{
						entries.get(j).setStateID(result[i]);
						j++;
						break;
					}							
			}
			
		}

		/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		timer.scheduleRepeating(6000);
		fillInterfaceControlsData();

		class MyHandler implements ClickHandler, KeyUpHandler {

			public void onClick(ClickEvent event) {
				submit();				
			}

			public void onKeyUp(KeyUpEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					submit();
				}
			}
		}
		MyHandler handler = new MyHandler();
		sendButton.addClickHandler(handler);
		txtPhoneNumber.addKeyUpHandler(handler);
		checkForImported();
	}

		private void fillInterfaceControlsData() {
			txtPhoneNumber.setText("");
			
			// We can add style names to widgets
			sendButton.addStyleName("sendButton");
			txtPhoneNumber.addStyleName("textField");
			txtPhoneNumber.setMaxLength(7);
			txtPhoneNumber.setSize("100", "");
			
			cmbNetCode.addItem("91");
			cmbNetCode.addItem("92");
			cmbNetCode.addItem("93");
			cmbNetCode.addItem("96");
			
			cmbDay.addItem("amanha");
			cmbDay.addItem("segunda-feira");
			cmbDay.addItem("terca-feira");
			cmbDay.addItem("quarta-feira");
			cmbDay.addItem("quinta-feira");
			cmbDay.addItem("sexta-feira");
			cmbDay.addItem("sabado");
			
			cmbClinica.addItem("Clinica Viver Saude");
			cmbClinica.addItem("Clinica Ser Saude");
					
			for (int i=10; i<=20; i++)
			{
				cmbHour.addItem(i+":00");
				for (int j=15; j<=45; j+=15)
					cmbHour.addItem(i+":"+j);
			}
			grid.setStyleName("smsGrid");

			// Add the nameField and sendButton to the RootPanel
			// Use RootPanel.get() to get the entire body element
			RootPanel.get("numberFieldContainer").add(txtPhoneNumber);
			RootPanel.get("sendButtonContainer").add(sendButton);
			RootPanel.get("gridContainer").add(grid);
			RootPanel.get("cmbTimeContainer").add(cmbHour);
			RootPanel.get("cmbNetworkCodeContainer").add(cmbNetCode);
			RootPanel.get("cmbDay").add(cmbDay);
			RootPanel.get("cmbClinica").add(cmbClinica);
			// Focus the cursor on the name field when the app loads
			txtPhoneNumber.setFocus(true);
			txtPhoneNumber.selectAll();
		}
	
	private void checkForImported() {
		if (Window.Location.getParameter("guid")!=null)
		{
		GWT.log("checking for imported...");
		
		smsService.getImported(Window.Location.getParameter("guid"), new AsyncCallback<SmsEntry[]>() {
			public void onFailure(Throwable caught) {	
				GWT.log("getImported returned error", caught);
				
			}

			public void onSuccess(SmsEntry[] result) {
				if (result != null)
				{
					GWT.log("results size: "+result.length);
					for (int i=0; i<result.length; i++)
					{
						result[i].setDate(new Date());
						//SmsEntry se = new SmsEntry("", "351"+cmbNetCode.getItemText(cmbNetCode.getSelectedIndex())+txtPhoneNumber.getText(), cmbHour.getValue(cmbHour.getSelectedIndex()), cmbDay.getValue(cmbDay.getSelectedIndex()),cmbClinica.getValue(cmbClinica.getSelectedIndex()));
						
						entries.add(result[i]);
						
					}
					bulksms = entries.size()-1;
					invokeNext();
					refreshGrid();
				}
			}
		});
			
		}
	}


	/**
	 * Send the name from the nameField to the server and wait for a response.
	 */
	
	private int bulksms=-1;
	private SmsEntry currentSMS;
	private void submitSMS(SmsEntry s) {
		sendButton.setEnabled(false);
		
		currentSMS = s;
	
		smsService.sendSMS(s,
				new AsyncCallback<SmsEntry>() {
					public void onFailure(Throwable caught) {
						sendButton.setEnabled(true);
						currentSMS.setState(SmsState.ERRO);
						invokeNext();
					}

					public void onSuccess(SmsEntry result) {
						currentSMS.setId(result.getId());
						currentSMS.setText(result.getText());
						sendButton.setEnabled(true);
						invokeNext();
						
					}
				});
	}

	protected void invokeNext() {
		if (bulksms>=0)
		{
			submitSMS(entries.get(bulksms));
			refreshGrid();
			bulksms--;
		}
	}

	public void submit() {
		if (txtPhoneNumber.getValue().length()!=7 || !txtPhoneNumber.getValue().matches("[0-9]+"))
		{
			Window.alert("Numero de telefone invalido.");
			return;
		}
		
		SmsEntry se = new SmsEntry("", "351"+cmbNetCode.getItemText(cmbNetCode.getSelectedIndex())+txtPhoneNumber.getText(), cmbHour.getValue(cmbHour.getSelectedIndex()), cmbDay.getValue(cmbDay.getSelectedIndex()),cmbClinica.getValue(cmbClinica.getSelectedIndex()));
		se.setDate(new Date());
		entries.add(se);
		submitSMS(se);
		
		refreshGrid();
	}

	private void refreshGrid() {
		grid.resizeRows(entries.size());
		SmsEntry e;
		for (int i=0; i<entries.size(); i++)
		{
			e=entries.get(i);
			grid.setText(i, 1, e.getDate().toString());
			grid.setText(i, 2, e.getPhoneNumber().substring(3));
			grid.setText(i, 3, e.getText());
			grid.setText(i, 0, e.getState().toString());
			switch(e.getState())
			{
			case PENDENTE:
			case ERRO:
				grid.getCellFormatter().setStyleName(i, 0, "redbg");
				break;
			case ENVIADO:
				grid.getCellFormatter().setStyleName(i, 0, "yellowbg");
				break;
			case ENTREGUE:				
				grid.getCellFormatter().setStyleName(i, 0, "greenbg");
				break;
			case SEM_CONFIRMACAO:
				break;
			default:
				break;
				
			}
			;			
		}		
	}
}
